﻿using MIO.Client.Util;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MIO.Client.RTT
{
    public class RTTHandler
    {
        public const long RTT_RSTMIN = 2;
        private const long RTT_RSTMAX = 60;
        private RTTInfo info;



        public RTTHandler(int defaultAckTimeout)
        {
            info = new RTTInfo() { Rtt = defaultAckTimeout };
            init();
        }

        public long RtoMilliseconds
        {
            get
            {
                return info.RtoMilliseconds;
            }
        }

        public void init()
        {
            long timestamp = DateUtil.GetCurrentTimeStamp();
            info.Rttval = 0.75;
            info.Rto = info.Rtt + (info.Rttval) * 4;
            info.Timestamp = timestamp;
        }

        public double minMax(double rto)
        {
            if (rto > RTT_RSTMAX)
                rto = RTT_RSTMAX;
            else if (rto < RTT_RSTMIN)
            {
                rto = RTT_RSTMIN;
            }
            return rto;
        }

        public void stop()
        {
            long currentTimestamp = DateUtil.GetCurrentTimeStamp();
            long stopTimestamp = currentTimestamp - info.Timestamp;
            info.Timestamp = currentTimestamp;
            double delte = 0;
            info.Rtt = stopTimestamp / 1000;
            delte = info.Rtt - info.Srtt;
            info.Srtt += delte / 8;
            info.Rttval += Math.Abs(delte) - info.Rttval / 4;
            info.Rto = minMax(info.Srtt + 4 * info.Rttval);

        }

        public void timeout()
        {
            info.Rto = minMax(info.Rto *= 2);
        }
    }
}
